package com.hlx.service;

import com.hlx.entity.DirectoryTree;
import com.hlx.entity.FileAttributes;
import com.hlx.util.AESUtil;
import com.hlx.util.ZipFile;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class FileTreeService {

    // 临时压缩文件
    private File zipFile;

    /**
     * 获取文件列表
     */
    public List<FileAttributes> fileList(File directory) throws Exception {
        List<FileAttributes> fileList = new ArrayList<>();
        if (directory.isDirectory()) {
            File[] files = directory.listFiles();
            for (File file : files) {
                // 过滤隐藏文件
                if (!file.isHidden()) {
                    // 获取文件属性
                    String fileName = file.getName();
                    String perR = file.canRead() ? "r" : "-";
                    String perW = file.canWrite() ? "w" : "-";
                    String perX = file.canExecute() ? "x" : "-";
                    String type = file.isDirectory() ? "d" : "f";
                    String path = file.getPath().replace("\\", "/");
                    String suffix = file.isDirectory() ? "-" : fileName.substring(fileName.lastIndexOf(".") + 1);
                    long lastModified = file.lastModified();

                    // 封装属性对象
                    FileAttributes attributes = new FileAttributes();
                    attributes.setName(fileName);
                    attributes.setSize(sizeFormat(file.length(), type));
                    attributes.setType(type);
                    attributes.setPermission(perR + ":" + perW + ":" + perX);
                    attributes.setPath(AESUtil.encrypt(path, AESUtil.KEY));// 加密
                    attributes.setSuffix(suffix);
                    attributes.setIcon("icon/" + iconFormat(suffix));

                    // 时间格式化
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    String time = dateFormat.format(new Date(lastModified));
                    attributes.setTime(time);

                    // 添加文件
                    fileList.add(attributes);
                }
            }
        }
        return fileList;
    }


    /**
     * 获取目录树
     */
    public DirectoryTree directoryTree(File directory) throws Exception {
        String name = directory.getName();
        String path = directory.getPath();
        path = path.replace("\\", "/"); // 字符转换
        path = AESUtil.encrypt(path, AESUtil.KEY); // 加密
        DirectoryTree root = new DirectoryTree(name, path);
        if (directory.isDirectory()) {
            File[] files = directory.listFiles();
            if (files != null) {
                for (File file : files) {
                    // 忽略隐藏文件和具体文件
                    if (file.isHidden() || file.isFile()) {
                        continue;
                    }
                    DirectoryTree childNode = directoryTree(file);
                    root.addChild(childNode);
                }
            }
        }
        return root;
    }


    /**
     * 单位转换
     */
    private String sizeFormat(long size, String type) {
        if (type.equals("d")) {
            return "-";
        }
        if (size < 1024) {
            return size + " B";
        } else if (size < 1024 * 1024) {
            return String.format("%.2f KB", (double) size / 1024);
        } else if (size < 1024 * 1024 * 1024) {
            return String.format("%.2f MB", (double) size / (1024 * 1024));
        } else {
            return String.format("%.2f GB", (double) size / (1024 * 1024 * 1024));
        }
    }


    /**
     * 类型图标
     */
    private String iconFormat(String suffix) {
        // 定义图标
        String[] text = {"txt", "log"};
        String[] zip = {"zip", "rar", "7z", "tar", "gz"};
        String[] word = {"doc", "docx"};
        String[] ppt = {"ppt", "pptx"};
        String[] xls = {"xls", "xlsx"};
        String[] pdf = {"pdf"};
        String[] xml = {"xml"};
        String[] sys = {"ini", "json5"};
        String[] img = {"jpg", "png", "jpeg"};
        String[] iso = {"iso", "img", "qcow2"};
        String[] xmind = {"xmind"};
        String[] psd = {"psd"};
        String[] dir = {"-"};
        String[] typora = {"md"};
        String[] medium = {"mp4", "mp3"};
        String[] code = {"java", "xml", "js", "css", "ts", "ets", "html", "htm", "xhtml", "json", "jsp"};
        String[] git = {"gitignore", "get"};
        String[] sql = {"sql"};

        String[][] concordance =
                {
                        text,
                        zip,
                        word,
                        ppt,
                        xls,
                        pdf,
                        xml,
                        sys,
                        img,
                        iso,
                        dir,
                        xmind,
                        psd,
                        typora,
                        code,
                        medium,
                        git,
                        sql
                };
        String[] icon = {
                "text.png",
                "zip.png",
                "word.png",
                "ppt.png",
                "xls.png",
                "pdf.png",
                "xml.png",
                "sys.png",
                "img.png",
                "iso.png",
                "dir.png",
                "xmind.png",
                "psd.png",
                "typora.png",
                "code.png",
                "medium.png",
                "git.png",
                "sql.png"
        };

        // 匹配图标
        String ico = "other.png";
        for (int i = 0; i < concordance.length; i++) {
            for (int j = 0; j < concordance[i].length; j++) {
                if (suffix.equalsIgnoreCase(concordance[i][j])) {
                    ico = icon[i];
                    break;
                }
            }
        }

        return ico;
    }

    /**
     * 文件下载
     */
    public ResponseEntity<FileSystemResource> download(File file) throws Exception {
        // 获取文件
        File[] fileList = {};
        if (file.isDirectory()) {
            fileList = file.listFiles();
        } else {
            fileList = new File[]{file};
        }

        // 文件压缩
        zipFile = new File(file.getName() + ".zip");
        ZipFile.filesToZip(fileList, zipFile);

        // 文件下载
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.valueOf(MediaType.APPLICATION_OCTET_STREAM_VALUE));
        headers.setContentDispositionFormData("attachment", new String(zipFile.getName().getBytes("utf-8"), "ISO-8859-1"));

        ResponseEntity responseEntity = new ResponseEntity<>(new FileSystemResource(zipFile), headers, HttpStatus.OK);
        return responseEntity;
    }


    /**
     * 删除文件
     */
    public void delete(File file) {
        File[] files = file.listFiles();
        if (files != null) {
            for (File f : files) {
                if (f.isDirectory()) {
                    delete(f);
                }
                f.delete();
            }
        }
        file.delete();
    }


    /**
     * 文件更名
     */
    public void update(File file, String newFile) {
        // 存放目录
        File parentFile = file.getParentFile();

        if (file.isFile()) {
            String path = file.getPath();
            int index = path.lastIndexOf(".");

            // 如果没有后缀，直接更名
            if (index == -1) {
                newFile = newFile;
            } else {
                String suffix = path.substring(index, path.length());
                newFile += suffix;
            }
        }

        file.renameTo(new File(parentFile, newFile));
    }

}